🏠↩︎ De vuelta a la página principal del curso
🚀 Objetivo de la unidad
Que el estudiante sea capaz de importar y exportar conjuntos de datos de y en diferentes formatos, así como ejecutar transformaciones básicas sobre estas utilizando dataframes y el paquete data.table.
🗂 ⬇ Descargar datos a utilizar en la práctica
Las siguientes instrucciones descargan los paquetes que utilizaremos en la práctica a tu equipo de cómputo. Por lo tanto, solo se debe correr una única vez (por equipo de cómputo).
# install.packages("data.table")
# install.packages("curl")
# install.packages("readxl")
# install.packages("foreign")
# install.packages("ggplot2")
Cargando un paquete Esta instrucción carga las funciones de los paquetes que utilizaremos a tu sesión de R actual. Por lo tanto, debemos correrla cada que vayamos a utilizar las funciones del paquete en una nueva sesión de R.
library(data.table)
library(readxl)
library(foreign)
library(ggplot2)
Recuerde que un data frame (y por lo tanto, un data table también) se compone de vectores. En el siguiente bloque de código, se instancian dos vectores inicialmente para después utilizarlos al crear un nuevo data table desde 0. 💡 Recordemos que los data tables heredan todas las propiedades de un data frame.
x <- 1:200
y <- rnorm(200, mean=70, sd=10)
dt <- data.table(id=x,
age=y)
Es importante denotar que los vectores que conformaran las columnas
de un data table al crearlo desde 0, deben ser del mismo tamaño.
Para convertir un dataframe a un datatable, utilizamos la misma función que empleamos para instanciar un data table desde 0.
x <- 1:200
y <- rnorm(200, mean=70, sd=10)
df <- data.frame(id=x,
age=y)
dt <- data.table(df)
Utilizamos la función fread(), que lee y convierte el
contenido del archivo en un data table.
💡 El formato ideal para leer y escribir datos en un entorno de
desarrollo orientado al análisis de conjuntos de datos (como R) es el
csv (“valores separados por comas” por sus siglas en inglés).
dt <- fread("./data/pob_censo_2020_inegi.csv")
💡 Note que la ruta para leer el archivo comienza en el directorio de trabajo de RStudio y que termina con el nombre completo (incluyendo sufijo) del archivo.
También es posible utilizar hipervínculos como ruta de lectura de un archivo.
dt_link <- fread("https://raw.githubusercontent.com/sarahiaguilar/R-4-SocialSci/gh-pages/data/pob_censo_2020_inegi.csv")
La función fread tiene parámetros que facilita la lectura de archivos con formatos más complejos. 💡 Recuerde que para conocer más acerca de una función específica (incluyendo sus parámetros y valores por defecto), corra “?” + el nombre de la función.
Por ejemplo, si el archivo no contiene un encabezado (nombres de
columnas), podemos utilizar el parámetro header para
indicarlo, o si el archivo está separado por un caracter distinto a unaa
coma, podemos utilizar el parámetro sep para indicarlo.
dt_txt <- fread("./data/pob_censo_2020_inegi.txt", header=FALSE, sep=";")
Para archivos xlsx utilizamos la función read_xlsx
del paquete readxl. Es necesario indicar como parámetro de
esta función el número de hoja que deseamos leer. También, es importante
destacar que esta función, a diferencia de laa función
fread(), no convierte el contenido del archivo en un data
table, por lo que es necesario hacer dicha conversión
posteriormente.
df_xlsx <- read_xlsx("./data/pob_censo_2020_inegi.xlsx", sheet=1) # Lee hoja número 1
df_xlsx <- data.table(df_xlsx) # Convierte a data table
Para archivos sav de SPSS o dta de STATA utilizamos funciones
del paquete foreign.
# df_spss <- read.spss("example.sav", to.data.frame=TRUE,
# use.value.labels=FALSE)
# df_stata <- read.dta("example.dta")
Las siguientes funciones nos permiten explorar rápidamente la composición de un data table. Este es un paso crucial para tener un entendimiento general de “cómo luce” el conjunto de datos y qué tipo de procesamiento requeriremos hacer sobre él.
💡 Es buena práctica mantener nuestro ambiente libre de variables que
ya no vamos a utilizar. Es posible eliminar variables desde nuestro
ambiente desde la ventana de Environment de RStudio, pero
también es posible con la función rm().
rm(df, df_xlsx, dt_link, dt_txt, x, y)
Las siguientes funciones nos permiten explorar
La función head() devuelve las primeras 6
observaciones de un data table.
head(dt)
## entidad_federativa edad hombres mujeres
## 1: Estados Unidos Mexicanos 0 916140 896837
## 2: Estados Unidos Mexicanos 1 967223 942735
## 3: Estados Unidos Mexicanos 2 1031816 NA
## 4: Estados Unidos Mexicanos 3 1060809 NA
## 5: Estados Unidos Mexicanos 4 1101494 NA
## 6: Estados Unidos Mexicanos 5 1106361 1072540
La función tail() devuelve las últimas 6
observaciones de un data table.
tail(dt)
## entidad_federativa edad hombres mujeres
## 1: Zacatecas 95 210 308
## 2: Zacatecas 96 193 253
## 3: Zacatecas 97 142 158
## 4: Zacatecas 98 119 166
## 5: Zacatecas 99 74 100
## 6: Zacatecas 100 y más 102 137
Tanto head() como tail(), pueden
recibir el argumento adicional n, que indicará cuántas
observaciones devolverá.
tail(dt, n=2) # Imprime las 2 últimas observaciones
## entidad_federativa edad hombres mujeres
## 1: Zacatecas 99 74 100
## 2: Zacatecas 100 y más 102 137
La función colnames() devuelve los nombres de las
variables de un data table.
colnames(dt)
## [1] "entidad_federativa" "edad" "hombres"
## [4] "mujeres"
La función dim() devuelve un vector de tamaño 2
con las dimensiones del data table. En la primer posición del vector, se
devolverá el número de observaciones, y en la segunda posición, el
número de variables.
dim(dt)
## [1] 3333 4
La función nrow() devuelve el número de
observaciones, y la función ncol(), el número de
variables.
nrow(dt)
## [1] 3333
ncol(dt)
## [1] 4
La función str() devuelve el tipo y tamaño de cada
vector que compone a un data table A esto se le conoce como la
“estructura” de un data frame.
str(dt)
## Classes 'data.table' and 'data.frame': 3333 obs. of 4 variables:
## $ entidad_federativa: chr "Estados Unidos Mexicanos" "Estados Unidos Mexicanos" "Estados Unidos Mexicanos" "Estados Unidos Mexicanos" ...
## $ edad : chr "0" "1" "2" "3" ...
## $ hombres : int 916140 967223 1031816 1060809 1101494 1106361 1057642 1087091 1140496 1061501 ...
## $ mujeres : int 896837 942735 NA NA NA 1072540 1037707 1059203 1093999 1047839 ...
## - attr(*, ".internal.selfref")=<externalptr>
La función summary() devuelve algunas de las
medidas de dispersón de las variables numéricas de un data table e
incluso el número de NAs por columna (en caso de que
haya).
summary(dt)
## entidad_federativa edad hombres mujeres
## Length:3333 Length:3333 Min. : 12 Min. : 28
## Class :character Class :character 1st Qu.: 4157 1st Qu.: 4662
## Mode :character Mode :character Median : 12771 Median : 13578
## Mean : 36806 Mean : 37741
## 3rd Qu.: 26646 3rd Qu.: 27476
## Max. :1174026 Max. :1218303
## NA's :3
Para data tables no muy grandes, podemos
utilizar la función View() que nos permite obtener una
visualización tabular completa de cómo se ve el conjunto de datos. La
visualización desplegada también la podemos obtener dando click sobre el
nombre del data taable en la venta de Environment de
RStudio.
Para simplificar el código, es muy importante asegurarnos que los nombres de columna de nuestro data table sean adecuados (comienzan con una letra, utilizan únicamente letras, números y guiones bajos (_) en lugar de espacios, no utilizar caracteres epeciales, y son nombres cortos, claros y concretos).
setnames() es una función que nos permitirá cambiar uno
o varios nombres de columna de un data.table de forma
segura.
setnames(dt, old=c("hombres", "mujeres"), new=c("pob_hombres", "pob mujeres"))
colnames(dt)
## [1] "entidad_federativa" "edad" "pob_hombres"
## [4] "pob mujeres"
💡 Para sustituir un valor y reemplazarlo por otro valor en un
vector, la gsub() resulta muy útil. En contexto, podemos
utilizar gsub() para reemplazar un caracter especial que se
repita en los nombres de columna de un data table.
setnames(dt,
old = colnames(dt),
new = gsub(" ", "_", colnames(dt))) # Reemplaza espacios por un guión bajo en los nombres de columna del data table
colnames(dt)
## [1] "entidad_federativa" "edad" "pob_hombres"
## [4] "pob_mujeres"
i en un data table💡 Recordemos que la forma general de sintaxis de un data table es
DT[i, j, by = k], y textualmente, se leería de la siguiente
forma:
DTi u ordena las filas
usando las columnas ij o calcula las nuevas
columnas jkiUna única observación basándonos en su índice.
dt[41, ]
## entidad_federativa edad pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos 40 1059322 1146683
Una secuencia de observaciones basándonos en sus índices.
dt[41:52, ]
## entidad_federativa edad pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos 40 1059322 1146683
## 2: Estados Unidos Mexicanos 41 624905 690335
## 3: Estados Unidos Mexicanos 42 928285 997622
## 4: Estados Unidos Mexicanos 43 768115 850194
## 5: Estados Unidos Mexicanos 44 681677 756448
## 6: Estados Unidos Mexicanos 45 919327 976618
## 7: Estados Unidos Mexicanos 46 718647 790847
## 8: Estados Unidos Mexicanos 47 725378 782495
## 9: Estados Unidos Mexicanos 48 763098 828232
## 10: Estados Unidos Mexicanos 49 685894 751877
## 11: Estados Unidos Mexicanos 50 890709 974467
## 12: Estados Unidos Mexicanos 51 519757 580730
Un conjunto de observaciones no secuenciales basándonos en su índices.
dt[c(41, 950, 1556), ]
## entidad_federativa edad pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos 40 1059322 1146683
## 2: Ciudad de México 40 84548 93207
## 3: México 40 148354 165687
Un conjunto de observaciones basándonos en una condición.
dt[entidad_federativa %in% c("Estados Unidos Mexicanos", "Ciudad de México", "México") & edad == 40, ]
## entidad_federativa edad pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos 40 1059322 1146683
## 2: Ciudad de México 40 84548 93207
## 3: México 40 148354 165687
* Ordenando las filas usando las columnas i
Con una variable de forma ascendente.
head(dt[order(pob_hombres), ])
## entidad_federativa edad pob_hombres pob_mujeres
## 1: Baja California Sur 99 12 35
## 2: Baja California Sur 100 y más 18 37
## 3: Baja California Sur 98 21 28
## 4: Baja California Sur 97 22 35
## 5: Colima 99 24 41
## 6: Aguascalientes 99 27 50
Con una variable de forma descendente
head(dt[order(-pob_hombres), ])
## entidad_federativa edad pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos 10 1174026 1125241
## 2: Estados Unidos Mexicanos 18 1172693 1134982
## 3: Estados Unidos Mexicanos 30 1148015 1218303
## 4: Estados Unidos Mexicanos 20 1146232 1161603
## 5: Estados Unidos Mexicanos 12 1146128 1103439
## 6: Estados Unidos Mexicanos 8 1140496 1093999
Con dos variables de forma ascendente
head(dt[order(entidad_federativa, pob_hombres), ])
## entidad_federativa edad pob_hombres pob_mujeres
## 1: Aguascalientes 99 27 50
## 2: Aguascalientes 100 y más 36 76
## 3: Aguascalientes 98 39 94
## 4: Aguascalientes 97 53 85
## 5: Aguascalientes 96 72 118
## 6: Aguascalientes 95 93 165
j en un data tablejUna única variable basándonos en su índice.
head(dt[, 2])
## edad
## 1: 0
## 2: 1
## 3: 2
## 4: 3
## 5: 4
## 6: 5
Una secuencia de variables basándonos en sus índices.
head(dt[, 3:4])
## pob_hombres pob_mujeres
## 1: 916140 896837
## 2: 967223 942735
## 3: 1031816 NA
## 4: 1060809 NA
## 5: 1101494 NA
## 6: 1106361 1072540
Un conjunto de variables no secuenciales basándonos en su índices.
head(dt[, c(1, 3:4)])
## entidad_federativa pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos 916140 896837
## 2: Estados Unidos Mexicanos 967223 942735
## 3: Estados Unidos Mexicanos 1031816 NA
## 4: Estados Unidos Mexicanos 1060809 NA
## 5: Estados Unidos Mexicanos 1101494 NA
## 6: Estados Unidos Mexicanos 1106361 1072540
Una única variable basándonos en su nombre de columna.
head(dt[, .(entidad_federativa)])
## entidad_federativa
## 1: Estados Unidos Mexicanos
## 2: Estados Unidos Mexicanos
## 3: Estados Unidos Mexicanos
## 4: Estados Unidos Mexicanos
## 5: Estados Unidos Mexicanos
## 6: Estados Unidos Mexicanos
También es posible escribir la instrucción así:
dt[, .(entidad_federativa)]. Observe que al ejecutar la
instrucción sin el .(), el resultado es un vector.
💡 La función unique() devuelve todos los valores
únicos de un vector. Esta función resulta útil para explorar rápidamente
los valores únicos de una variable categórica.
unique(dt[, entidad_federativa])
## [1] "Estados Unidos Mexicanos" "Aguascalientes"
## [3] "Baja California" "Baja California Sur"
## [5] "Campeche" "Coahuila de Zaragoza"
## [7] "Colima" "Chiapas"
## [9] "Chihuahua" "Ciudad de México"
## [11] "Durango" "Guanajuato"
## [13] "Guerrero" "Hidalgo"
## [15] "Jalisco" "México"
## [17] "Michoacán de Ocampo" "Morelos"
## [19] "Nayarit" "Nuevo León"
## [21] "Oaxaca" "Puebla"
## [23] "Querétaro" "Quintana Roo"
## [25] "San Luis Potosí" "Sinaloa"
## [27] "Sonora" "Tabasco"
## [29] "Tamaulipas" "Tlaxcala"
## [31] "Veracruz de Ignacio de la Llave" "Yucatán"
## [33] "Zacatecas"
Un conjunto de variables no secuenciales basándonos en su nombre de columna.
head(dt[, .(entidad_federativa, pob_hombres, pob_mujeres)])
## entidad_federativa pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos 916140 896837
## 2: Estados Unidos Mexicanos 967223 942735
## 3: Estados Unidos Mexicanos 1031816 NA
## 4: Estados Unidos Mexicanos 1060809 NA
## 5: Estados Unidos Mexicanos 1101494 NA
## 6: Estados Unidos Mexicanos 1106361 1072540
Esta otra forma es también válida y debe ser utilizada en caso de que los nombres de columnas tengan caracteres especiales.
head(dt[, c("entidad_federativa", "pob_hombres", "pob_mujeres")])
## entidad_federativa pob_hombres pob_mujeres
## 1: Estados Unidos Mexicanos 916140 896837
## 2: Estados Unidos Mexicanos 967223 942735
## 3: Estados Unidos Mexicanos 1031816 NA
## 4: Estados Unidos Mexicanos 1060809 NA
## 5: Estados Unidos Mexicanos 1101494 NA
## 6: Estados Unidos Mexicanos 1106361 1072540
* Calculando las nuevas columnas j Al calcular una
nueva columna en un data table, una iteración por cada fila ocurre de
forma implícita.
Calculando nueva variable desde 0.
dt[, indice := 1:nrow(dt)]
head(dt)
## entidad_federativa edad pob_hombres pob_mujeres indice
## 1: Estados Unidos Mexicanos 0 916140 896837 1
## 2: Estados Unidos Mexicanos 1 967223 942735 2
## 3: Estados Unidos Mexicanos 2 1031816 NA 3
## 4: Estados Unidos Mexicanos 3 1060809 NA 4
## 5: Estados Unidos Mexicanos 4 1101494 NA 5
## 6: Estados Unidos Mexicanos 5 1106361 1072540 6
Calculando nueva variable con variables ya existentes.
dt[, pob_total := pob_hombres + pob_mujeres]
head(dt)
## entidad_federativa edad pob_hombres pob_mujeres indice pob_total
## 1: Estados Unidos Mexicanos 0 916140 896837 1 1812977
## 2: Estados Unidos Mexicanos 1 967223 942735 2 1909958
## 3: Estados Unidos Mexicanos 2 1031816 NA 3 NA
## 4: Estados Unidos Mexicanos 3 1060809 NA 4 NA
## 5: Estados Unidos Mexicanos 4 1101494 NA 5 NA
## 6: Estados Unidos Mexicanos 5 1106361 1072540 6 2178901
💡 En R, las operaciones con NA siempre resultan
en NA.
Calculando variable con variables ya existentes y condicionales.
# Se sobreescribe una variable ya existente (pob_total)
dt[, pob_hombres := ifelse(test = pob_hombres < 0, # ¿La población de hombres en la fila es menor a 0?
yes = 0, # Si la condición es verdadera, devuelve 0
no = pob_hombres)] # Si la condición es falsa, devuelve la misma población de hombres en la fila
head(dt)
## entidad_federativa edad pob_hombres pob_mujeres indice pob_total
## 1: Estados Unidos Mexicanos 0 916140 896837 1 1812977
## 2: Estados Unidos Mexicanos 1 967223 942735 2 1909958
## 3: Estados Unidos Mexicanos 2 1031816 NA 3 NA
## 4: Estados Unidos Mexicanos 3 1060809 NA 4 NA
## 5: Estados Unidos Mexicanos 4 1101494 NA 5 NA
## 6: Estados Unidos Mexicanos 5 1106361 1072540 6 2178901
k en un data tableAntes de agrupar por las columnas k, es necesario
indicar al menos una operación con una columna j.
jUna única operación
dt[entidad_federativa != "Estados Unidos Mexicanos", sum(pob_hombres)]
## [1] 61337196
dt[, .N] # .N es un conteo de observaciones
## [1] 3333
Múltiples operaciones
dt[entidad_federativa == "Estados Unidos Mexicanos", .(sum(pob_hombres), sum(pob_mujeres))]
## V1 V2
## 1: 61337196 NA
Renombrando las operaciones
dt[entidad_federativa != "Estados Unidos Mexicanos", .(sum_pob_h = sum(pob_hombres), sum_pob_m = sum(pob_mujeres))]
## sum_pob_h sum_pob_m
## 1: 61337196 64403442
kPor una única variable
head(dt[, .(sum_pob_h = sum(pob_hombres), sum_pob_m = sum(pob_mujeres)), by = entidad_federativa])
## entidad_federativa sum_pob_h sum_pob_m
## 1: Estados Unidos Mexicanos 61337196 NA
## 2: Aguascalientes 695934 728165
## 3: Baja California 1896493 1864308
## 4: Baja California Sur 403966 390639
## 5: Campeche 454789 469280
## 6: Coahuila de Zaragoza 1560595 1580017
Por múltiples variables
head(dt[, .(sum_pob_h = sum(pob_hombres), sum_pob_m = sum(pob_mujeres)), by = .(entidad_federativa, edad)])
## entidad_federativa edad sum_pob_h sum_pob_m
## 1: Estados Unidos Mexicanos 0 916140 896837
## 2: Estados Unidos Mexicanos 1 967223 942735
## 3: Estados Unidos Mexicanos 2 1031816 NA
## 4: Estados Unidos Mexicanos 3 1060809 NA
## 5: Estados Unidos Mexicanos 4 1101494 NA
## 6: Estados Unidos Mexicanos 5 1106361 1072540
En este caso, el resultado a laa instrucción anterior luce igual al data table opriginal.
NAs. 4.4. Reemplace
los NAs por la media de observaciones similares a
estas. 4.5. Responda: ¿cuál es la entidad federativa que mayor relación
hombres-mujeres (cuántos hombres hay por cada mujer en la entidad
federativa)? 4.6. Cree una nueva variable que refiera a la regiones
geográficas* a la que pertenezca cada entidad federativa. 4.7. Cree un
nuevo data table con la población de mujeres entre 18 y 65 años por
región geográfica y guárdelo en un nuevo archivo csv dentro de la
carpeta datos “datos” del proyecto. 4.8. Cree un nuevo data table con la
población total de 18 años por entidad federativa y en él cree una nueva
variable que refiera al porcentaje de la población de 18 años que
representa cada entidad federativa de la población total de 18 años de
Estados Unidos Mexicanos.